; Basic sanity-check of most extensions

(def is-float  '(eq (type-of res) type-float))
(def is-i      '(eq (type-of res) type-i))
(def is-list   '(or (eq res nil) (eq (type-of res) type-list)))
(def is-array  '(eq (type-of res) type-array))
(def is-symbol '(eq (type-of res) type-symbol))
(def is-true   '(eq res true))

; The first element in each row is an expression that is evaluated to res. The second
; element is an expression that can use res and must evaluate to true for the test to pass.
(def test-cmds '(
        ((timeout-reset)                             is-true)
        ((get-ppm)                                   is-float)
        ((get-ppm-age)                               is-float)
        ((get-encoder)                               is-float)
        ((get-encoder-error-rate)                    is-float)
        ((set-servo 0)                               is-true)
        ((get-vin)                                   is-float)
        ((select-motor 1)                            is-true)
        ((get-selected-motor)                        (= res 1))
        ((get-bms-val 'bms-v-tot)                    is-float)
        ((get-bms-val 'bms-v-charge)                 is-float)
        ((get-bms-val 'bms-i-in-ic)                  is-float)
        ((get-bms-val 'bms-ah-cnt)                   is-float)
        ((get-bms-val 'bms-wh-cnt)                   is-float)
        ((get-bms-val 'bms-cell-num)                 is-i)
        ((get-bms-val 'bms-temp-adc-num)             is-i)
        ((get-bms-val 'bms-temp-ic)                  is-float)
        ((get-bms-val 'bms-temp-hum)                 is-float)
        ((get-bms-val 'bms-hum)                      is-float)
        ((get-bms-val 'bms-temp-cell-max)            is-float)
        ((get-bms-val 'bms-soc)                      is-float)
        ((get-bms-val 'bms-can-id)                   is-i)
        ((get-bms-val 'bms-ah-cnt-chg-total)         is-float)
        ((get-bms-val 'bms-wh-cnt-chg-total)         is-float)
        ((get-bms-val 'bms-ah-cnt-dis-total)         is-float)
        ((get-bms-val 'bms-wh-cnt-dis-total)         is-float)
        ((get-bms-val 'bms-msg-age)                  is-float)
        ((get-adc 0)                                 is-float)
        ((get-adc 1)                                 is-float)
        ((get-adc 2)                                 is-float)
        ((get-adc-decoded 0)                         is-float)
        ((get-adc-decoded 1)                         is-float)
        ((systime)                                   (eq (type-of res) type-u32))
        ((secs-since 0)                              is-float)
        ((set-aux 1 0)                               is-true)
        ((set-aux 2 0)                               is-true)
        ((get-imu-rpy)                               is-list)
        ((get-imu-quat)                              is-list)
        ((get-imu-acc)                               is-list)
        ((get-imu-gyro)                              is-list)
        ((get-imu-mag)                               is-list)
        ((get-imu-acc-derot)                         is-list)
        ((get-imu-gyro-derot)                        is-list)
        ((send-data '(1 2 3))                        is-true)
        ((send-data "Hello")                         is-true)
        ((sleep 0.01)                                is-true)
        ((get-remote-state)                          is-list)
        ((sysinfo 'hw-name)                          is-array)
        ((sysinfo 'fw-ver)                           is-list)
        ((sysinfo 'has-phase-filters)                is-symbol)
        ((sysinfo 'uuid)                             is-list)
        ((sysinfo 'runtime)                          (eq (type-of res) type-u64))
        ((sysinfo 'git-branch)                       is-array)
        ((sysinfo 'git-hash)                         is-array)
        ((sysinfo 'compiler)                         is-array)
        ((app-adc-detach 0 0)                        is-true)
        ((app-adc-override 0 0.0)                    is-true)
        ((app-ppm-detach 0)                          is-true)
        ((app-ppm-override 0.0)                      is-true)
        ((set-remote-state 0 0 0 0 0)                is-true)
        ((app-disable-output 0)                      is-true)
        ((app-is-output-disabled)                    (eq res false))
        ((app-pas-get-rpm)                           is-float)
        ((set-current 0.0)                           is-true)
        ((set-current 0.0 0.0)                       is-true)
        ((set-current-rel 0.0)                       is-true)
        ((set-duty 0.0)                              is-true)
        ((set-brake 0.0)                             is-true)
        ((set-brake-rel 0.0)                         is-true)
        ((set-handbrake 0.0)                         is-true)
        ((set-handbrake-rel 0.0)                     is-true)
        ((set-rpm 0.0)                               is-true)
        ((set-pos 0.0)                               is-true)
        ((foc-openloop 0.0 0.0)                      is-true)
        ((foc-beep 4000.0 0 0)                       is-true)
        ((get-current)                               is-float)
        ((get-current-dir)                           is-float)
        ((get-current-in)                            is-float)
        ((get-id)                                    is-float)
        ((get-iq)                                    is-float)
        ((get-vd)                                    is-float)
        ((get-vq)                                    is-float)
        ((get-duty)                                  is-float)
        ((get-rpm)                                   is-float)
        ((get-temp-fet)                              is-float)
        ((get-temp-fet 1)                            is-float)
        ((get-temp-fet 2)                            is-float)
        ((get-temp-fet 3)                            is-float)
        ((get-temp-mot)                              is-float)
        ((get-speed)                                 is-float)
        ((get-dist)                                  is-float)
        ((get-dist-abs)                              is-float)
        ((get-batt)                                  is-float)
        ((get-fault)                                 is-i)
        ((get-ah)                                    is-float)
        ((get-wh)                                    is-float)
        ((get-ah-chg)                                is-float)
        ((get-wh-chg)                                is-float)
        ((setup-ah)                                  is-float)
        ((setup-wh)                                  is-float)
        ((setup-ah-chg)                              is-float)
        ((setup-wh-chg)                              is-float)
        ((setup-current)                             is-float)
        ((setup-current-in)                          is-float)
        ((setup-num-vescs)                           is-i)
        ((canset-current 0 0 0)                      is-true)
        ((canset-current-rel 0 0)                    is-true)
        ((canset-current-rel 0 0 0)                  is-true)
        ((canset-duty 0 0)                           is-true)
        ((canset-brake 0 0)                          is-true)
        ((canset-brake-rel 0 0)                      is-true)
        ((canset-rpm 0 0)                            is-true)
        ((canset-pos 0 0)                            is-true)
        ((canset-current 0 0)                        is-true)
        ((canget-current 0)                          is-float)
        ((canget-current-dir 0)                      is-float)
        ((canget-current-in 0)                       is-float)
        ((canget-duty 0)                             is-float)
        ((canget-rpm 0)                              is-float)
        ((canget-temp-fet 0)                         is-float)
        ((canget-temp-motor 0)                       is-float)
        ((canget-speed 0)                            is-float)
        ((canget-dist 0)                             is-float)
        ((canget-ppm 0)                              is-float)
        ((canget-adc 0)                              is-float)
        ((canget-adc 1)                              is-float)
        ((can-list-devs)                             is-list)
        ((can-send-sid 0 0)                          is-true)
        ((can-send-eid 0 0)                          is-true)
        ((sin 2.1252)                                is-float)
        ((cos 2.1252)                                is-float)
        ((tan 2.1252)                                is-float)
        ((asin 0.1252)                               is-float)
        ((acos 0.1252)                               is-float)
        ((atan 0.1252)                               is-float)
        ((atan2 0.1252 0.2)                          is-float)
        ((pow 0.1252 1.1)                            is-float)
        ((sqrt 0.1252)                               is-float)
        ((log 0.1252)                                is-float)
        ((log10 0.1252)                              is-float)
        ((deg2rad 0.1252)                            is-float)
        ((rad2deg 0.1252)                            is-float)
        ((abs -0.1252)                               is-float)
        ((abs -3)                                    (eq res 3))
        ((throttle-curve 0.2 0.9 0.6 2)              is-float)
        ((bits-enc-int 0 3 1 1)                      (= res 8))
        ((bits-dec-int 6 1 2)                        (= res 3))
        ((raw-adc-current 1 2)                       is-float)
        ((raw-adc-current 1 2 1)                     is-float)
        ((raw-adc-voltage 1 2)                       is-float)
        ((raw-adc-voltage 1 2 1)                     is-float)
        ((raw-mod-alpha)                             is-float)
        ((raw-mod-beta)                              is-float)
        ((raw-mod-alpha-measured)                    is-float)
        ((raw-mod-beta-measured)                     is-float)
        ((raw-hall 1)                                is-list)
        ((raw-hall 1 5)                              is-list)
        ((uart-start 115200)                         is-true)
        ((uart-start 115200 'half-duplex)            is-true)
        ((uart-write "abc")                          is-true)
        ((i2c-start)                                 is-true)
        ((i2c-start 'rate-400k)                      is-true)
        ((i2c-start 'rate-400k 'pin-rx 'pin-tx)      is-true)
        ((gpio-configure 'pin-rx 'pin-mode-in)       is-true)
        ((gpio-write 'pin-rx 1)                      is-true)
        ((conf-set 'max-speed (conf-get 'max-speed)) is-true)
        ((conf-set-pid-offset 10 false)              is-true)
        ((conf-measure-res 5)                        is-float)
        ((conf-measure-res 5 50)                     is-float)
        ((eeprom-store-f 2 2.2)                      is-true)
        ((eeprom-read-f 2)                           is-float)
        ((eeprom-store-i 2 15)                       is-true)
        ((eeprom-read-i 2)                           (= res 15))
        ((reverse '(1 2 3))                          (eq res '(3 2 1)))
        ((length '(1 2))                             (= res 2))
        ((str-from-n 14)                             (eq res "14"))
        ((str-merge "a" "bC")                        (eq res "abC"))
        ((str-to-i "187")                            (= res 187))
        ((str-to-f "2.11")                           is-float)
        ((str-part "Hello World!" 6)                 (eq res "World!"))
        ((str-part "Hello World!" 6 2)               (eq res "Wo"))
        ((str-split "1 2" " ")                       (eq res '("1" "2")))
        ((str-replace "aBc" "B" "a")                 (eq res "aac"))
        ((str-replace "aBc" "B")                     (eq res "ac"))
        ((str-replace "aBc" "B")                     (eq res "ac"))
        ((str-to-upper "TesTt")                      (eq res "TESTT"))
        ((str-to-lower "TesTt")                      (eq res "testt"))
        ((str-cmp "Hello" "World")                   (= res -15))
        ((str-len "hello")                           (= res 5))
        ((to-str '(1 2))                             (eq res "(1 2)"))
        ((to-str-delim "q" '(1 2) 3)                 (eq res "(1 2)q3"))
        ((buflen "aa")                               (= res 3))
        ((uavcan-last-rawcmd 1)                      is-list)
        ((plot-init "A" "B")                         is-true)
        ((plot-add-graph "c")                        is-true)
        ((plot-set-graph 0)                          is-true)
        ((plot-send-points 1 2)                      is-true)
        ((ioboard-get-adc 2 1)                       is-float)
        ((ioboard-get-digital 2 1)                   is-i)
        ((ioboard-set-digital 2 1 0)                 is-true)
        ((ioboard-set-pwm 2 1 0.2)                   is-true)
        ((log-stop 2)                                is-true)
        ((log-send-f32 1 1 2 3)                      is-true)
        ((log-send-f64 1 1 '(2 3) 4)                 is-true)
        ((gnss-lat-lon)                              is-list)
        ((gnss-height)                               is-float)
        ((gnss-speed)                                is-float)
        ((gnss-hdop)                                 is-float)
        ((gnss-date-time)                            is-list)
        ((gnss-age)                                  is-float)
        ((stats 'stat-speed-avg)                     is-float)
        ((stats 'stat-speed-max)                     is-float)
        ((stats 'stat-power-avg)                     is-float)
        ((stats 'stat-power-max)                     is-float)
        ((stats 'stat-current-avg)                   is-float)
        ((stats 'stat-current-max)                   is-float)
        ((stats 'stat-temp-mosfet-avg)               is-float)
        ((stats 'stat-temp-mosfet-max)               is-float)
        ((stats 'stat-temp-motor-avg)                is-float)
        ((stats 'stat-temp-motor-max)                is-float)
        ((stats 'stat-count-time)                    is-float)
        ((stats-reset)                               is-true)
        ((override-temp-motor 0.2)                   is-true)
))

(def test-res (loopforeach i test-cmds
        (let (
                (cmd (ix i 0))
                (res-expr (ix i 1))
                (res (eval cmd))
                (ok (eval (eval res-expr)))
            )
            (if (eq ok true)
                {
                    (print (str-merge "Testing " (to-str cmd) "... OK! Res: " (to-str res)))
                    true
                }
                {
                    (print (str-merge "Testing " (to-str cmd) "... Failed. Res: " (to-str res) " res-expr: " (to-str ok)))
                    (break false)
                }
            )
)))

(if test-res
    (print "All tests passed!")
    (print "One or more tests failed.")
)
